//
// Created by zengao on 2022/12/29.
//

#ifndef C100_LEXER_H
#define C100_LEXER_H

#include <string_view>
#include <memory>

namespace C100 {
    enum class TokenKind {
        Add,
        Sub,
        Mul,
        Div,
        Num,
        LParent,
        RParent,
        LBrace,
        RBrace,
        Identifier,
        Semicolon,
        Assign,
        Equal,
        PipeEqual,
        Greater,
        GreaterEqual,
        Lesser,
        LesserEqual,
        If,
        Else,
        Eof
    };
    struct SourceLocation {
        int line;
        int col;
    };

    class Token {
    public:
        TokenKind kind;
        int value;
        SourceLocation location;
        std::string_view content;
    };

    class Lexer {
    private:
        char curChar{' '};
        char cursor{0};
        int line{0};
        int lineHead{0};
    public:
        std::shared_ptr<Token> currentToken;
        std::string_view sourceCode;
    public:
        Lexer(const char *code) {
            sourceCode = code;
        }

        void getNextToken();

        void getNextChar();
        void expectToken(TokenKind kind);

    private:
        bool isLetter();

        bool isDigit();

        bool isLetterOrDigit();

        char peekChar(int distance);

        const char *getTokenSimpleSpelling(TokenKind kind);
    };

}


#endif //C100_LEXER_H
